package me.luger.project.base.config.nutz;

import com.alibaba.druid.pool.DruidDataSource;
import me.luger.core.commom.util.ClazzUtil;
import me.luger.core.commom.util.StringUtil;
import me.luger.core.dao.nutz.config.NutzDaoBaseConfig;
import org.nutz.dao.impl.NutDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by a on 2016/12/28.
 */
@Configuration
public class MainDaoConfig extends NutzDaoBaseConfig {
    @Value("${nutz.default.db.url}")
    private String dbUrl;
    @Value("${nutz.default.db.user}")
    private String dbUser;
    @Value("${nutz.default.db.password}")
    private String dbPassword;
    @Value("${nutz.default.db.driver}")
    private String dbDriver;
    @Value("${nutz.default.db.type}")
    private String dbType;
    @Value("${nutz.default.db.id}")
    private String dbId;
    @Value("${nutz.default.db.packages.to.scan}")
    private String scanPackages;

    @Bean(name="fofDataSource")
    public DataSource getDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(dbDriver);
        druidDataSource.setUrl(dbUrl);
        druidDataSource.setUsername(dbUser);
        druidDataSource.setPassword(dbPassword);
        druidDataSource.setDbType(dbType);
        druidDataSource.setName(dbId);
        druidDataSource.setValidationQuery("SELECT 'x'");
        druidDataSource.setInitialSize(1);
        try {
            druidDataSource.setFilters("stat, wall");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return druidDataSource;
    }

    @Bean(name = "fofNutDao")
    @Primary
    public NutDao initNutzDao(){
        List<Class> clazzes = ClazzUtil.getClasssFromPackage(scanPackages);
        NutDao nutDao = new NutDao(getDataSource());
        nutDao.setRunner(nutzDaoRunner());
        for(Class clazz : clazzes){
            try {
                clazz = ClazzUtil.filterGgilibClazz(clazz);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            Repository repository = (Repository) clazz.getAnnotation(Repository.class);
            String beanName = repository.value();
            if(StringUtil.isBlank(beanName)){
                beanName = StringUtil.firstChar2LowerCast(ClazzUtil.getBeanName(clazz));
            }
            ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext;
            DefaultListableBeanFactory dbf = (DefaultListableBeanFactory) context.getBeanFactory();
            BeanDefinitionBuilder dataSourceBuider = BeanDefinitionBuilder.genericBeanDefinition(clazz);
            dataSourceBuider.addPropertyValue("dao",nutDao);
            dbf.registerBeanDefinition(beanName, dataSourceBuider.getBeanDefinition());
        }
        return nutDao;
    }
}
